package com.grouplay.service.impl;

import com.grouplay.dao.IGroupDao;
import com.grouplay.dao.ITransferRecordDao;
import com.grouplay.dao.IUserDao;
import com.grouplay.dao.IUserGroupDao;
import com.grouplay.entity.Group;
import com.grouplay.entity.TransferRecord;
import com.grouplay.entity.User;
import com.grouplay.entity.UserGroup;
import com.grouplay.service.IUserService;
import com.grouplay.utils.SHA256Util;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

@Service("userService")
public class UserServiceImpl implements IUserService {

    @Autowired
    private IUserDao userDao;
    @Autowired
    private IUserGroupDao userGroupDao;
    @Autowired
    private ITransferRecordDao transferRecordDao;
    @Autowired
    private IGroupDao groupDao;

    Logger logger = Logger.getLogger(UserServiceImpl.class);

    @Override
    public boolean insert(User user) {
        if (userDao.findUserByEmail(user.getEmail()) != null){
            logger.info("邮箱：" + user.getEmail() + "已经被注册，注册失败");
            return false;
        }
        if (userDao.findUserByName(user.getName()) != null) {
            logger.info("用户名：" + user.getName() + "已经被注册，注册失败");
            return false;
        }
        String password_salt = "";
        for (int i = 0; i < 5; i ++){
            password_salt += (int) (Math.random() * 9 + 1);
        }
        user.setPasswordSalt(password_salt);
        user.setPassword(SHA256Util.getSHA256String(password_salt + user.getPassword()));
        user.setBalance(1000D);
        userDao.insert(user);
        logger.info("用户名：" + user.getName() + "，邮箱：" + user.getEmail() + "注册成功");
        return true;
    }

    @Override
    public User login(String email, String password) {
        User user = userDao.findUserByEmail(email);
        if (user != null && user.getPassword().equals(SHA256Util.getSHA256String(user.getPasswordSalt() + password))){
            logger.info("用户名：" + user.getName() + "，邮箱：" + user.getEmail() + "登录成功");
            return user;
        }
        logger.info("邮箱：" + email + "登录失败");
        return null;
    }

    @Override
    public boolean setNewPassword(String email, String password) {
        User user = userDao.findUserByEmail(email);
        if (user != null) {
            user.setPassword(SHA256Util.getSHA256String(user.getPasswordSalt() + password));
            userDao.updateUser(user);
            logger.info("用户名：" + user.getName() + "，邮箱：" + user.getEmail() + "修改密码成功");
            return true;
        }
        logger.info("邮箱：" + email + "修改密码失败");
        return false;
    }

    @Override
    public boolean serNewName(User user) {
        try {
            if (userDao.findUserByName(user.getName()) != null) {
                return false;
            }
            userDao.updateUser(user);
            return true;
        } catch (Exception e){
            e.printStackTrace();
            return false;
        }
    }

    @Override
    public Double findBalanceById(Integer id) {
        return userDao.findBalanceById(id);
    }

    @Override
    public boolean transferMoney(String targetName, Integer sourceId, Double money) {
        if (money <= 0) {
            return false;
        }
        User targetUser = userDao.findUserByName(targetName);
        if (targetUser == null && targetUser.getId() != sourceId) {
            return false;
        }
        double sourceBalance = userDao.findBalanceById(sourceId);
        if (sourceBalance < money) {
            return false;
        }
        User sourceUser = new User();
        sourceUser.setId(sourceId);
        sourceUser.setBalance(sourceBalance - money);
        targetUser.setBalance(targetUser.getBalance() + money);
        TransferRecord transferRecord = new TransferRecord();
        transferRecord.setSourceId(sourceId);
        transferRecord.setTargetId(targetUser.getId());
        transferRecord.setMoney(money);
        transferRecord.setDate(new Date());
        userDao.updateUserBalance(sourceUser);
        userDao.updateUserBalance(targetUser);
        transferRecordDao.insert(transferRecord);
        return true;
    }

    @Override
    public boolean pay(Integer groupId, Integer uid) {
        List<Group> groups = groupDao.findMyJoinGroupsIsEndAndIsNotPay(uid);
        Group group = null;
        for (int i = 0; i < groups.size(); i ++) {
            if (groups.get(i).getId() == groupId) {
                group = groups.get(i);
            }
        }
        group.setNumberOfMembers(userGroupDao.findNumberOfMembersByGroupId(group.getId()));
        group.setNeedMoney((group.getTotalBudget() - group.getPersonalBudget()) / (group.getNumberOfMembers() - 1));
        Double sourceBalance = userDao.findBalanceById(uid);
        Double money = group.getNeedMoney();
        if (sourceBalance < money) {
            return false;
        }
        User targetUser = userDao.findUserByName(group.getLeaderName());
        User sourceUser = new User();
        UserGroup ug = new UserGroup();
        sourceUser.setId(uid);
        sourceUser.setBalance(sourceBalance - money);
        ug.setUid(uid);
        ug.setGid(groupId);
        targetUser.setBalance(targetUser.getBalance() + money);
        TransferRecord transferRecord = new TransferRecord();
        transferRecord.setSourceId(uid);
        transferRecord.setTargetId(targetUser.getId());
        transferRecord.setMoney(money);
        transferRecord.setGroupId(groupId);
        transferRecord.setDate(new Date());
        ug.setIsPay(1);
        userGroupDao.updateIsPay(ug);
        userDao.updateUserBalance(sourceUser);
        userDao.updateUserBalance(targetUser);
        transferRecordDao.insert(transferRecord);
        return true;
    }

    @Override
    public List<TransferRecord> findMyTransferRecordsByUid(Integer uid) {
        return transferRecordDao.findMyTransferRecordsByUid(uid);
    }
}
